/* 类中属性 / 方法的装饰器 */

// 在给实例设置私有属性的时候，触发装饰器函数执行，来给属性进行装饰

const test = (target, name, descriptor) => {
    // target: Demo.prototype
    // name:"x"
    // descriptor: {configurable: true, enumerable: true, writable: true, initializer: f}  x 的属性描述符,初始值基于initializer函数
    console.log(target, name, descriptor)
    // 返回值必循是一个规则的描述对象，也就是对name修饰属性 / 方法的描述
    return {
        enumerable:false,
        initializer(){
            return "@@"
        }
    }
}


// 创建只读属性的装饰器
const readyonly = (_, name, descriptor) => {
    // 把属性修饰符的name / 方法 改为只读的规则
    descriptor.writable = false
}
// 创建记录执行时间日志的装饰器
const loggerTime = (_, name, descriptor) => {
    // 把之前的写的函数赋值给func
    let func = descriptor.value;
    // 然后把函数重写
    descriptor.value = function (...params) {
        // this:实例
        console.time(name)
        let res = func.call(this, params)
        console.timeEnd(name)
        return res
    }
}

class Demo {
    // @test x = 100
    @test
    @readyonly
    x = 100

    // @test getX(){}
    @readyonly
    @loggerTime
     getX() {
        for (let i = 0; i < 100000000 ; i++) {
        }
        return this.x
    }
}

let d = new Demo()
console.log(d)
console.log(d.getX())